import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
import { NzMessageService } from 'ng-zorro-antd/message';
import { NzUploadChangeParam } from 'ng-zorro-antd/upload';

interface Point {
  x: number;
  y: number;
}

interface Segment {
  index: number;
  start: Point;
  end: Point;
  distance: number;
  color: string;
}


@Component({
  selector: 'app-demo-5',
  templateUrl: './demo-5.component.html',
  styleUrls: ['./demo-5.component.less']
})
export class Demo5Component {
  @ViewChild('measureImage') imageRef!: ElementRef<HTMLImageElement>;

  // 图片相关
  imageUrl: string | null = 'https://test.dingsing-medical.com:9000/dingsing/default/2025/10/30/95e777bc3efa4f72a702f9e9b9b5425f.jpg'; // 当前测量图片URL
  // imageUrl: string | null = null;
  isUploading = false;
  uploadAction = 'https://www.mocky.io/v2/5cc8019d300000980a055e76';
  uploadHeaders = { authorization: 'authorization-text' };

  // 测量相关
  private colorPalette = ['#ff4d4f', '#1890ff', '#52c41a', '#faad14', '#722ed1'];
  segments: Segment[] = [];
  currentSegment: { index: number; start: Point; color: string } | null = null;
  tempPoint: Point | null = null;
  currentTempDistance = 0;
  showTempDistance = false;
  pixelsPerCm = 0; // 校准后的像素/厘米（核心：替换默认值）

  // 校准相关（新增）
  isCalibrating = false; // 是否处于校准模式
  calibrateStart: Point | null = null; // 校准线段起点
  calibrateEnd: Point | null = null; // 校准线段终点
  calibrateActualCm = 0; // 用户输入的校准线段实际长度（厘米）
  calibratePixelDistance = 0; // 校准线段的像素距离

  // 鼠标位置（十字准星）
  mouseX = 0;
  mouseY = 0;

  constructor(private message: NzMessageService) { }

  ngOnInit(): void {
    // 初始化默认值（未校准前仍用理论值，校准后覆盖）
    const dpr = window.devicePixelRatio || 1;
    this.pixelsPerCm = (96 * dpr) / 2.54;
  }

  // 上传逻辑（不变）
  handleChange(info: NzUploadChangeParam): void {
    const file = info.file;
    if (file.status === 'uploading') {
      this.isUploading = true;
      return;
    }
    if (file.status === 'done') {
      this.isUploading = false;
      if (file.originFileObj) {
        this.readLocalFile(file.originFileObj);
      } else {
        this.imageUrl = (file.response as any)?.url || null;
        this.imageUrl ? this.resetAll() : this.message.error('获取图片失败');
      }
      return;
    }
    if (file.status === 'error') {
      this.isUploading = false;
      this.message.error('上传失败');
    }
  }

  // 读取本地文件（不变）
  private readLocalFile(file: File): void {
    if (!this.isImageFile(file)) {
      this.message.error('请上传图片文件（jpg、png等）');
      return;
    }
    const reader = new FileReader();
    reader.onload = (e) => {
      this.imageUrl = (e.target as FileReader).result as string;
      this.resetAll();
      this.message.success('图片上传成功，建议先校准后测量');
    };
    reader.readAsDataURL(file);
  }

  // 图片验证（不变）
  private isImageFile(file: File): boolean {
    const isImageType = file.type.startsWith('image/');
    const fileName = file.name.toLowerCase();
    const validExts = ['.jpg', '.jpeg', '.png', '.gif', '.bmp'];
    const isValidExt = validExts.some(ext => fileName.endsWith(ext));
    return isImageType && isValidExt;
  }

  // 进入校准模式（新增）
  startCalibrate(): void {
    if (!this.imageUrl) {
      this.message.warning('请先上传图片');
      return;
    }
    this.isCalibrating = true;
    this.calibrateStart = null;
    this.calibrateEnd = null;
    this.calibrateActualCm = 0;
    this.calibratePixelDistance = 0;
    this.message.info('校准模式：请在图片上点击标记已知长度的线段起点');
  }

  // 退出校准模式（新增）
  cancelCalibrate(): void {
    this.isCalibrating = false;
    this.calibrateStart = null;
    this.calibrateEnd = null;
  }

  // 校准线段标记（新增）
  handleCalibrateClick(event: MouseEvent): void {
    const point = this.getImageRelativePoint(event);
    if (!this.calibrateStart) {
      this.calibrateStart = point;
      this.message.info('已标记校准起点，请点击标记终点');
    } else {
      this.calibrateEnd = point;
      this.calibratePixelDistance = this.calculatePixelDistance(this.calibrateStart, this.calibrateEnd);
      this.message.info(`校准线段像素距离：${this.calibratePixelDistance}px，请输入实际长度（厘米）`);
    }
  }

  // 确认校准（核心：计算准确的pixelsPerCm）
  confirmCalibrate(): void {
    if (!this.calibrateStart || !this.calibrateEnd || this.calibrateActualCm <= 0) {
      this.message.warning('请完成校准线段标记并输入有效实际长度');
      return;
    }
    // 核心公式：像素/厘米 = 校准线段像素距离 / 实际厘米数
    this.pixelsPerCm = this.calibratePixelDistance / this.calibrateActualCm;
    this.isCalibrating = false;
    this.message.success(`校准完成！当前像素/厘米：${this.pixelsPerCm.toFixed(2)}px/cm`);
    // 重置测量数据（确保新校准值生效）
    this.resetAll();
  }

  // 鼠标移动（含校准模式）
  onImageMouseMove(event: MouseEvent): void {
    if (!this.imageUrl) return;

    // 鼠标位置更新（十字准星）
    const wrapper = this.imageRef.nativeElement.parentElement;
    if (wrapper) {
      const rect = wrapper.getBoundingClientRect();
      this.mouseX = event.clientX - rect.left;
      this.mouseY = event.clientY - rect.top;
    }

    // 校准模式：实时更新校准线段临时点
    if (this.isCalibrating && this.calibrateStart) {
      const tempPoint = this.getImageRelativePoint(event);
      this.calibratePixelDistance = this.calculatePixelDistance(this.calibrateStart, tempPoint);
      return;
    }

    // 普通测量模式
    if (this.currentSegment) {
      this.tempPoint = this.getImageRelativePoint(event);
      this.currentTempDistance = this.calculateDistance(this.currentSegment.start, this.tempPoint);
    }
  }

  // 图片点击（区分校准/测量模式）
  onImageClick(event: MouseEvent): void {
    if (this.isCalibrating) {
      this.handleCalibrateClick(event); // 校准模式
      return;
    }

    // 普通测量模式
    if (!this.imageUrl) {
      this.message.warning('请先上传图片');
      return;
    }
    const imagePoint = this.getImageRelativePoint(event);
    if (!this.currentSegment) {
      const segmentIndex = this.segments.length + 1;
      this.currentSegment = {
        index: segmentIndex,
        start: imagePoint,
        color: this.colorPalette[segmentIndex % this.colorPalette.length]
      };
      this.showTempDistance = true;
    } else {
      const distance = this.calculateDistance(this.currentSegment.start, imagePoint);
      this.segments.push({
        index: this.currentSegment.index,
        start: this.currentSegment.start,
        end: imagePoint,
        distance,
        color: this.currentSegment.color
      });
      this.currentSegment = null;
      this.tempPoint = null;
    }
  }

  // 计算纯像素距离（无单位转换）
  private calculatePixelDistance(p1: Point, p2: Point): number {
    const dx = p2.x - p1.x;
    const dy = p2.y - p1.y;
    return Math.sqrt(dx * dx + dy * dy);
  }

  // 计算实际距离（厘米，使用校准后的pixelsPerCm）
  private calculateDistance(p1: Point, p2: Point): number {
    const pixelDistance = this.calculatePixelDistance(p1, p2);
    return pixelDistance / this.pixelsPerCm; // 核心：用校准后的值
  }

  // 坐标转换（不变）
  private getImageRelativePoint(event: MouseEvent): Point {
    const image = this.imageRef.nativeElement;
    const imageRect = image.getBoundingClientRect();
    const wrapper = image.parentElement;
    if (!wrapper) return { x: 0, y: 0 };
    const clickX = event.clientX - imageRect.left;
    const clickY = event.clientY - imageRect.top;
    const scaleX = image.naturalWidth / imageRect.width;
    const scaleY = image.naturalHeight / imageRect.height;
    return {
      x: Math.round(clickX * scaleX),
      y: Math.round(clickY * scaleY)
    };
  }

  // 线段显示长度（不变）
  getLineLength(p1: Point, p2: Point): number {
    const image = this.imageRef.nativeElement;
    const rect = image.getBoundingClientRect();
    const scale = rect.width / image.naturalWidth;
    return this.calculatePixelDistance(p1, p2) * scale;
  }

  // 线段旋转角度（不变）
  getLineTransform(p1: Point, p2: Point): string {
    const angle = Math.atan2(p2.y - p1.y, p2.x - p1.x) * (180 / Math.PI);
    return `rotate(${angle}deg) translate(0, -50%)`;
  }

  // 显示坐标转换（不变）
  getDisplayPosition(value: number, isX: boolean): number {
    const image = this.imageRef.nativeElement;
    const rect = image.getBoundingClientRect();
    const scale = isX ? rect.width / image.naturalWidth : rect.height / image.naturalHeight;
    return value * scale;
  }

  // 删除线段（不变）
  deleteSegment(index: number): void {
    this.segments = this.segments.filter(seg => seg.index !== index);
    this.segments.forEach((seg, i) => seg.index = i + 1);
  }

  // 重置所有（不变）
  resetAll(): void {
    this.segments = [];
    this.currentSegment = null;
    this.tempPoint = null;
    this.currentTempDistance = 0;
    this.showTempDistance = false;
    this.isCalibrating = false;
    this.calibrateStart = null;
    this.calibrateEnd = null;
  }

  // trackBy（不变）
  trackByIndex(index: number): number {
    return index;
  }
}
